package com.xudu.qojbackend.controller;


import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.gson.Gson;

import com.xudu.qojbackend.annotation.AuthCheck;
import com.xudu.qojbackend.common.DeleteRequest;
import com.xudu.qojbackend.common.ErrorCode;
import com.xudu.qojbackend.common.Result;
import com.xudu.qojbackend.constant.UserConstant;
import com.xudu.qojbackend.exception.ServiceException;
import com.xudu.qojbackend.exception.ThrowUtils;
import com.xudu.qojbackend.model.dto.question.*;
import com.xudu.qojbackend.model.dto.user.LoginRequest;
import com.xudu.qojbackend.model.entity.Question;
import com.xudu.qojbackend.model.vo.UserVO;
import com.xudu.qojbackend.service.QuestionService;
import com.xudu.qojbackend.service.UserService;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * @className: UserControllerImpl
 * @description: TODO
 * @author: xudu
 * @create: 2024-10-10
 */
@RestController
@RequestMapping("/question")
@Slf4j
public class QuestionController {

    @Resource
    private UserService userService;

    @Resource
    private QuestionService questionService;

    // 全局的gson工具
    private static final Gson gson = new Gson();

    /**
     * 创建题目
     */
    @ApiOperation("题目添加接口")
    @PostMapping("/add")
    public Result addQuestion(@RequestBody QuestionAddRequest questionAddRequest) {
        if(questionAddRequest == null){
            throw new ServiceException(ErrorCode.PARAMS_ERROR);
        }
        Question question = new Question();
        BeanUtils.copyProperties(questionAddRequest, question);
        List<String> tags = questionAddRequest.getTags();
        if (tags != null) {
            question.setTags(gson.toJson(tags));
        }
        List<JudgeCase> judgeCase = questionAddRequest.getJudgeCase();
        if (judgeCase != null) {
            question.setJudgeCase(gson.toJson(judgeCase));
        }
        JudgeConfig judgeConfig = questionAddRequest.getJudgeConfig();
        if (judgeConfig != null) {
            question.setJudgeConfig(gson.toJson(judgeConfig));
        }
        questionService.validQuestion(question, true);
        UserVO loginUser = userService.getLoginUser();
        question.setUserId(loginUser.getId());
        boolean save = questionService.save(question);
        ThrowUtils.throwIf(!save, ErrorCode.OPERATION_ERROR);

        return Result.success(question.getId());
    }

    /**
     * 删除题目
     */
    @ApiOperation("题目删除接口")
    @PostMapping("/delete")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public Result deleteQuestion(@RequestBody DeleteRequest deleteRequest) {

        if (deleteRequest == null || deleteRequest.getId() <= 0){
            throw new ServiceException(ErrorCode.PARAMS_ERROR);
        }

        UserVO loginUser = userService.getLoginUser();
        Long id = deleteRequest.getId();
        // 判断是否存在
        Question oldQuestion = questionService.getById(id);
        ThrowUtils.throwIf(oldQuestion == null, ErrorCode.NOT_FOUND_ERROR);
        // 仅本人或管理员可删除
        if (!oldQuestion.getUserId().equals(loginUser.getId()) && !userService.isAdmin()) {
            throw new ServiceException(ErrorCode.NO_AUTH_ERROR);
        }
        boolean b = questionService.removeById(id);
        return Result.success(b);
    }

    /**
     * 更新题目
     */
    @ApiOperation("题目更新接口")
    @PostMapping("/update")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public Result updateQuestion(@RequestBody QuestionUpdateRequest questionUpdateRequest) {
        if (questionUpdateRequest == null || questionUpdateRequest.getId() <= 0){
            throw new ServiceException(ErrorCode.PARAMS_ERROR);
        }
        Question question = new Question();
        BeanUtils.copyProperties(questionUpdateRequest, question);
        List<String> tags = questionUpdateRequest.getTags();
        if (tags != null) {
            question.setTags(gson.toJson(tags));
        }
        List<JudgeCase> judgeCase = questionUpdateRequest.getJudgeCase();
        if (judgeCase != null) {
            question.setJudgeCase(gson.toJson(judgeCase));
        }
        JudgeConfig judgeConfig = questionUpdateRequest.getJudgeConfig();
        if (judgeConfig != null) {
            question.setJudgeConfig(gson.toJson(judgeConfig));
        }
        questionService.validQuestion(question, false);

        Long id = questionUpdateRequest.getId();
        Question oldQuestion = questionService.getById(id);
        ThrowUtils.throwIf(oldQuestion == null, ErrorCode.NOT_FOUND_ERROR);
        boolean b = questionService.updateById(question);
        return Result.success(b);

    }

    /**
     * 分页获取题目列表
     */
    @ApiOperation("分页获取题目列表接口")
    @PostMapping("/list/page/vo")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public Result listQuestionVOByPage(@RequestBody QuestionQueryRequest questionQueryRequest) {
        int pageNum = questionQueryRequest.getPageNum();
        int pageSize = questionQueryRequest.getPageSize();
        //  限制爬虫
        ThrowUtils.throwIf(pageSize > 20, ErrorCode.PARAMS_ERROR);

        Page<Question> questionPage = questionService.page(new Page<>(pageNum, pageSize),
                questionService.getQueryWrapper(questionQueryRequest));
        return Result.success(questionService.getQuestionVOPage(questionPage));
    }


    /**
     * 分页获取当前用户创建的题目列表
     */
    @ApiOperation("分页获取当前用户创建的题目列表接口")
    @PostMapping("/my/list/page/vo")
    public Result listMyQuestionVOByPage(@RequestBody QuestionQueryRequest questionQueryRequest) {
        if (questionQueryRequest == null){
            throw new ServiceException(ErrorCode.PARAMS_ERROR);
        }
        UserVO loginUser = userService.getLoginUser();
        questionQueryRequest.setUserId(loginUser.getId());
        int pageNum = questionQueryRequest.getPageNum();
        int pageSize = questionQueryRequest.getPageSize();
        //  限制爬虫
        ThrowUtils.throwIf(pageSize > 20, ErrorCode.PARAMS_ERROR);

        Page<Question> questionPage = questionService.page(new Page<>(pageNum, pageSize),
                questionService.getQueryWrapper(questionQueryRequest));
        return Result.success(questionService.getQuestionVOPage(questionPage));
    }

    /**
     * 分页获取题目列表(管理员)
     */
    @ApiOperation("分页获取题目列表接口（管理员）")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    @PostMapping("/my/list/page")
    public Result listQuestionByPage(@RequestBody QuestionQueryRequest questionQueryRequest) {
        if (questionQueryRequest == null){
            throw new ServiceException(ErrorCode.PARAMS_ERROR);
        }

        int pageNum = questionQueryRequest.getPageNum();
        int pageSize = questionQueryRequest.getPageSize();
        //  限制爬虫
        ThrowUtils.throwIf(pageSize > 20, ErrorCode.PARAMS_ERROR);

        Page<Question> questionPage = questionService.page(new Page<>(pageNum, pageSize),
                questionService.getQueryWrapper(questionQueryRequest));
        return Result.success(questionPage);
    }

    /**
     * 更新题目
     */
    @ApiOperation("题目编辑接口（用户）")
    @PostMapping("/edit")
    public Result editQuestion(@RequestBody QuestionUpdateRequest questionUpdateRequest) {
        if (questionUpdateRequest == null || questionUpdateRequest.getId() <= 0){
            throw new ServiceException(ErrorCode.PARAMS_ERROR);
        }
        Question question = new Question();
        BeanUtils.copyProperties(questionUpdateRequest, question);
        List<String> tags = questionUpdateRequest.getTags();
        if (tags != null) {
            question.setTags(gson.toJson(tags));
        }
        List<JudgeCase> judgeCase = questionUpdateRequest.getJudgeCase();
        if (judgeCase != null) {
            question.setJudgeCase(gson.toJson(judgeCase));
        }
        JudgeConfig judgeConfig = questionUpdateRequest.getJudgeConfig();
        if (judgeConfig != null) {
            question.setJudgeConfig(gson.toJson(judgeConfig));
        }
        questionService.validQuestion(question, false);

        Long id = questionUpdateRequest.getId();
        Question oldQuestion = questionService.getById(id);
        ThrowUtils.throwIf(oldQuestion == null, ErrorCode.NOT_FOUND_ERROR);

        if (!oldQuestion.getUserId().equals(userService.getLoginUser().getId()) && !userService.isAdmin()) {
            throw new ServiceException(ErrorCode.NO_AUTH_ERROR);
        }
        boolean b = questionService.updateById(question);
        return Result.success(b);

    }


}
